#ifndef INIT_HANDLER_HPP
#define INIT_HANDLER_HPP

#include "HttpHandler.hpp"
#include "DBhandler.hpp"
#include "file_counter.hpp"

namespace xzt
{
    class InitHandler
    {
        using Server = httplib::Server;

    public:
        static void DoInit(Server &svr, const std::string &photo_dir = PHOTO_DIR)
        {
            // 路由相关初始化
            RouterInitHandler::photo_router(svr);
            RouterInitHandler::user_router(svr);
            RouterInitHandler::post_router(svr);
            RouterInitHandler::comment_router(svr);
            RouterInitHandler::event_router(svr);
            OtherInitHandler::admin_router(svr);

            // 数据库相关初始化
            DBInitHandler::InitDB();
        }

    private:
        class RouterInitHandler
        {
        public:
        // url设定规则：
        // 1. 不可省略的参数用冒号(:)表示，如/photos/:photo_id
        //    解析方式：req.path_params.at("photo_id");
        // 2. 可选参数用问号(?)表示，如/photos?sort=likes
        //    解析方式：req.get_param_value("sort");     // 若参数不存在，返回空字符串

            static void photo_router(Server &svr)
            {
                // 上传图片
                svr.Post("/photos/upload", PhotoHttpHandler::Upload);
                // 获取所有图片
                // -- 内部解析sort参数，决定按什么排序 {实际url: http://localhost:8090/photos?sort=likes}
                svr.Get("/photos", PhotoHttpHandler::GetAllPhotos);
                // 获取某个用户的所有图片
                svr.Get("/photos/user/:user_id", PhotoHttpHandler::GetPhotosByUser);
                // 获取某个图片
                svr.Get("/photos/:photo_id", PhotoHttpHandler::GetPhoto);
                // 获取分类下的所有图片
                // -- 内部解析sort参数
                svr.Get("/photos/category/:category", PhotoHttpHandler::GetPhotosByCategory);
                // 点赞某个图片
                // -- form-data中需要包含当前user_id {实际url: http://localhost:8090/photos/1/like}
                svr.Post("/photos/:photo_id/like", PhotoHttpHandler::LikePhoto);
                // 删除某个图片
                svr.Delete("/photos/:photo_id", PhotoHttpHandler::DeletePhoto);
            }
            static void user_router(Server &svr)
            {
                // 注册用户
                svr.Post("/register", UserHttpHandler::Register);
                // 登录用户
                svr.Post("/login", UserHttpHandler::Login);
                // 获取用户信息
                svr.Get("/user/:user_id", UserHttpHandler::GetUserInfo);
                // 修改用户信息
                svr.Put("/user/:user_id", UserHttpHandler::UpdateUserInfo);
                // 获取所有用户信息
                svr.Get("/users", UserHttpHandler::GetAllUsers);
                // 删除用户
                svr.Delete("/user/:user_id", UserHttpHandler::DeleteUser);
                // 根据用户名搜索用户
                // -- {实际url: http://localhost:8090/photos/users/search?username=exampleUsername}
                svr.Get("/users/search", UserHttpHandler::SearchUserByName);
                // 用户封禁
                svr.Put("/users/:user_id/block", UserHttpHandler::BlockUser);
                // 用户解封
                svr.Put("/users/:user_id/unblock", UserHttpHandler::UnblockUser);
            }
            static void post_router(Server &svr)
            {
                // 发布新帖子
                svr.Post("/posts/upload", PostHttpHandler::UploadPost);
                // 获取所有帖子
                // -- {实际url: http://localhost:8090/posts?sort=likes}
                svr.Get("/posts", PostHttpHandler::GetAllPosts);
                // 点赞某个帖子
                svr.Post("/posts/:post_id/like", PostHttpHandler::LikePost);
                // 删除某个帖子
                svr.Delete("/posts/:post_id", PostHttpHandler::DeletePost);
                // 模糊搜索帖子
                // -- {实际url: http://localhost:8090/posts/search?keyword=exampleKeyword}
                svr.Get("/posts/search", PostHttpHandler::SearchPost);
                // 获取某个用户的所有帖子
                svr.Get("/posts/user/:user_id", PostHttpHandler::GetPostsByUser);
            }
            static void comment_router(Server &svr)
            {
                // 发布新评论 -- 评论对象是帖子
                svr.Post("/comments/:post_id/upload", CommentHttpHandler::UploadComment);
                // 获取某个帖子的所有评论
                svr.Get("/comments/:post_id", CommentHttpHandler::GetCommentsByPost);
                // 删除某个评论
                svr.Delete("/comments/:comment_id", CommentHttpHandler::DeleteComment);
            }
            static void event_router(Server &svr)
            {
                // 发布新活动
                svr.Post("/events/upload", EventHttpHandler::UploadEvent);
                // 获取所有活动
                // -- {实际url: http://localhost:8090/events?sort=likes}
                svr.Get("/events", EventHttpHandler::GetAllEvents);
                // 点赞某个活动
                svr.Post("/events/:event_id/like", EventHttpHandler::LikeEvent);
                // 删除某个活动
                svr.Delete("/events/:event_id", EventHttpHandler::DeleteEvent);
                // 模糊搜索活动
                // -- {实际url: http://localhost:8090/events/search?keyword=exampleKeyword}
                svr.Get("/events/search", EventHttpHandler::SearchEvent);
                // 获取某个用户的所有活动
                svr.Get("/events/user/:user_id", EventHttpHandler::GetEventsByUser);
                // 置顶某个活动
                svr.Put("/events/:event_id/top", EventHttpHandler::TopEvent);
                // 取消置顶某个活动
                svr.Put("/events/:event_id/untop", EventHttpHandler::UntopEvent);
            }
        };

        class OtherInitHandler
        {
        public:
            static void admin_router(Server &svr)
            {
                // 设定登录验证接口
                svr.Post("/admin/login", OtherHttpHandler::AdminLogin);
            }
        };

        class DBInitHandler
        {
        public:
            static void InitDB()
            {
                // 需要初始化photos表对应的Handler类中的成员变量photo_num
                int num = count_files(PHOTO_DIR);
                if (num == -1)
                {
                    LOG_FATAL("Failed to count files in %s", PHOTO_DIR);
                    assert(false);
                }
                PhotoDBHandler::photo_num = num;
                LOG_INFO("初始化数据库成功，共有 %d 张照片", num);
            }
        };
    };
}

#endif // INIT_HANDLER_HPP